<template>
  <div :class="prefixCls" class="relative w-full h-full px-4">
    <div class="flex items-center absolute right-4 top-4">
      <AppDarkModeToggle class="enter-x mr-2" v-if="!sessionTimeout" />
      <AppLocalePicker
        class="text-white enter-x xl:text-gray-600"
        :show-text="false"
        v-if="!sessionTimeout && showLocale"
      />
    </div>

    <span class="-enter-x xl:hidden">
      <AppLogo :alwaysShowTitle="true" />
    </span>

    <div class="container relative h-full py-2 mx-auto sm:px-10">
      <div class="flex h-full">
        <div class="hidden min-h-full pl-4 mr-4 xl:flex xl:flex-col xl:w-6/12">
          <AppLogo class="-enter-x" />
          <div class="my-auto">
            <img
              :alt="appTitle"
              src="../../../assets/svg/login-box-bg.svg"
              class="w-1/2 -mt-16 -enter-x"
            />
            <div class="mt-10 font-medium text-white dark:text-gray-500 -enter-x">
              <span class="inline-block mt-4 text-3xl"> {{ appDescription }}</span>
            </div>
            <div class="mt-5 font-normal text-white dark:text-gray-500 -enter-x">
              {{ appSubdescription }}
            </div>
          </div>
        </div>
        <div class="flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12">
          <div
            :class="`${prefixCls}-form`"
            class="relative w-full px-5 py-8 mx-auto my-auto rounded-md shadow-md xl:ml-16 xl:bg-transparent sm:px-8 xl:p-4 xl:shadow-none sm:w-3/4 lg:w-2/4 xl:w-auto enter-x"
          >
            <h2 class="mb-6 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-left">
              {{ t('routes.basic.oAuthLogin') }}
            </h2>
            <Form class="p-4 enter-x" ref="formRef">
              <FormItem name="avatar" class="enter-x">
                <Avatar :src="formData.avatar" :size="72" class="!mx-auto !block" />
                <div class="text-center">{{ getTimeGreeting }}, {{ formData.name }}</div>
                <div class="text-center">{{
                  t('sys.oauth.providerTitle', [formData.provider])
                }}</div>
              </FormItem>

              <FormItem name="userName" class="enter-x" v-show="resultData.status === 'info'">
                <Input
                  size="large"
                  v-model:value="formData.userName"
                  :placeholder="t('sys.login.userName')"
                >
                  <template #prefix>
                    <Icon icon="ant-design:user-outlined" />
                  </template>
                </Input>
              </FormItem>
              <FormItem name="password" class="enter-x" v-show="resultData.status === 'info'">
                <InputPassword
                  size="large"
                  visibilityToggle
                  v-model:value="formData.password"
                  :placeholder="t('sys.login.password')"
                >
                  <template #prefix>
                    <Icon icon="carbon-password" />
                  </template>
                </InputPassword>
              </FormItem>

              <ARow class="enter-x" v-show="resultData.status === 'info'">
                <ACol :xs="24" :md="8">
                  <Tooltip :title="t('sys.oauth.loginBindTipTitle')" placement="bottom">
                    <Button block type="primary" @click="handleLoginBind" :loading="loading">
                      {{ t('sys.oauth.loginBindTitle') }}
                    </Button>
                  </Tooltip>
                </ACol>
                <ACol :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2">
                  <Tooltip :title="t('sys.oauth.loginOneKeyTipTitle')" placement="bottom">
                    <Button block type="primary" @click="handleLoginOneKey" :loading="loading">
                      {{ t('sys.oauth.loginOneKeyTitle') }}
                    </Button>
                  </Tooltip>
                </ACol>
                <ACol :md="7" :xs="24">
                  <Tooltip :title="t('sys.oauth.backloginTipTitle')" placement="bottom">
                    <Button block @click="handleBack">{{ t('sys.login.backSignIn') }}</Button>
                  </Tooltip>
                </ACol>
              </ARow>

              <div v-show="resultData.status !== 'info'">
                <Result
                  :status="resultData.status"
                  :title="resultData.title"
                  :sub-title="resultData.subTitle"
                >
                  <template #extra>
                    <a-button key="back" @click="handleBack">
                      {{ t('sys.login.backSignIn') }}
                    </a-button>
                  </template>
                </Result>
                <div>
                  <Descriptions>
                    <DescriptionItem />
                  </Descriptions>
                </div>
              </div>
            </Form>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import {
    Form,
    Result,
    Descriptions,
    Input,
    Button,
    Avatar,
    Tooltip,
    Row,
    Col,
  } from 'ant-design-vue';

  import { AppDarkModeToggle, AppLocalePicker, AppLogo } from '@/components/Application';
  import Icon from '@/components/Icon/Icon.vue';

  // import { useGlobSetting } from '@/hooks/setting';
  import { useDesign } from '@/hooks/web/useDesign';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useMessage } from '@/hooks/web/useMessage';
  import { useLocaleStore } from '@/store/modules/locale';
  import { useIdentityStore } from '@/store/modules/identity';
  import { usePreferenceStore } from '@/store/modules/preference';

  import { JsonWebToken } from '#/identity';
  import { loginBind, loginOneKey } from '@/api/identity';

  import { router } from '@/router';
  import { PageEnum } from '@/enums/pageEnum';

  import { getHashURLSearchParams } from '@/utils/common';

  import { reactive, ref, toRaw, computed, watchEffect } from 'vue';

  interface ResultData {
    status: 'error' | 'success' | 'warning' | 'info' | '404' | '403' | '500';
    title: string;
    subTitle: string;
  }

  const FormItem = Form.Item;
  const ACol = Col;
  const ARow = Row;
  const InputPassword = Input.Password;
  const DescriptionItem = Descriptions.Item;

  defineProps({
    sessionTimeout: {
      type: Boolean,
    },
  });

  // const globSetting = useGlobSetting();
  const { prefixCls } = useDesign('oauthcallback');
  const { t } = useI18n();
  const { notification, createMessage } = useMessage();
  const localeStore = useLocaleStore();
  const identityStore = useIdentityStore();

  const getTimeGreeting = computed(() => {
    const currentDate = new Date();
    const currentHours: number = currentDate.getHours();
    let timeGreeting = t('sys.greet.hello');
    if (currentHours >= 0 && currentHours < 12) {
      timeGreeting = t('sys.greet.goodMorning');
    } else if (currentHours >= 12 && currentHours < 18) {
      timeGreeting = t('sys.greet.goodAfternoon');
    } else if (currentHours >= 18 && currentHours < 23) {
      timeGreeting = t('sys.greet.goodNight');
    }
    return timeGreeting;
  });

  const loading = ref(false);

  const resultData = reactive<ResultData>({
    status: 'info',
    title: t('common.processingText'),
    subTitle: '',
  });
  const formData = reactive({
    id: '',
    provider: '',
    name: '',
    avatar: '',
    userName: '',
    password: '',
  });

  watchEffect(async () => {
    loading.value = true;
    try {
      const url = window.location.hash;
      formData.id = getHashURLSearchParams(url, 'id') as string;
      if (formData.id) {
        formData.provider = getHashURLSearchParams(url, 'type') as string;
        formData.name = getHashURLSearchParams(url, 'name') as string;
        formData.avatar = getHashURLSearchParams(url, 'avatar') as string;
      } else {
        const token = getHashURLSearchParams(url, 'token');
        if (token) {
          const token = JSON.parse(token) as JsonWebToken;
          await identityStore.loginEnd(token);
          const userInfo = await identityStore.afterLoginAction();
          if (userInfo) {
            await router.replace(PageEnum.BASE_HOME);
            notification.success({
              message: t('sys.login.loginSuccessTitle'),
              description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.NickName}`,
              duration: 3,
            });
          } else {
            resultData.status = 'error';
            resultData.title = t('sys.login.loginFailedTitle');
            resultData.subTitle = '';
          }
        }
      }
    } catch (error: any) {
      resultData.status = 'error';
      resultData.title = t('sys.login.loginFailedTitle');
      resultData.subTitle = error?.message;
    } finally {
      loading.value = false;
    }
  });

  /** 处理绑定并登录 */
  async function handleLoginBind() {
    loading.value = true;
    try {
      if (
        formData.userName === undefined ||
        formData.userName === null ||
        formData.userName === ''
      ) {
        createMessage.error(t('sys.login.userNamePlaceholder'));
        return;
      }
      if (
        formData.password === undefined ||
        formData.password === null ||
        formData.password === ''
      ) {
        createMessage.error(t('sys.login.passwordPlaceholder'));
        return;
      }
      const dto = toRaw({
        ProviderKey: formData.id,
        Account: formData.userName,
        Password: formData.password,
      });
      const result = await loginBind(dto);
      if (result.Succeeded) {
        const token = result.Data;
        await identityStore.loginEnd(token);
        const userInfo = await identityStore.afterLoginAction();
        if (userInfo) {
          await router.replace(PageEnum.BASE_HOME);
          notification.success({
            message: t('sys.login.loginSuccessTitle'),
            description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.NickName}`,
            duration: 3,
          });
        } else {
          resultData.status = 'error';
          resultData.title = t('sys.login.loginFailedTitle');
          resultData.subTitle = '';
        }
      }
    } finally {
      loading.value = false;
    }
  }

  /** 处理新建并登录 */
  async function handleLoginOneKey() {
    loading.value = true;
    try {
      const dto = toRaw({
        ProviderKey: formData.id,
        Account: formData.userName,
        Password: formData.password,
      });
      const result = await loginOneKey(dto);
      if (result.Succeeded) {
        const token = result.Data;
        await identityStore.loginEnd(token);
        const userInfo = await identityStore.afterLoginAction();
        if (userInfo) {
          await router.replace(PageEnum.BASE_HOME);
          notification.success({
            message: t('sys.login.loginSuccessTitle'),
            description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.NickName}`,
            duration: 3,
          });
        } else {
          resultData.status = 'error';
          resultData.title = t('sys.login.loginFailedTitle');
          resultData.subTitle = '';
        }
      }
    } finally {
      loading.value = false;
    }
  }

  /** 处理返回 */
  async function handleBack() {
    router.push(PageEnum.BASE_HOME);
  }

  const showLocale = localeStore.getShowPicker;
  // const title = computed(() => globSetting?.title ?? '');
  const preferenceStore = usePreferenceStore();
  const appTitle = computed(() => preferenceStore.getAppTitle ?? '');
  const appDescription = computed(() => preferenceStore.getAppDescription ?? '');
  const appSubdescription = computed(() => preferenceStore.getAppSubdescription ?? '');
</script>
<style lang="less">
  @prefix-cls: ~'@{namespace}-oauthcallback';
  @logo-prefix-cls: ~'@{namespace}-app-logo';
  @countdown-prefix-cls: ~'@{namespace}-countdown-input';
  @captcha-prefix-cls: ~'@{namespace}-captcha-input';
  @dark-bg: #293146;

  html[data-theme='dark'] {
    .@{prefix-cls} {
      background-color: @dark-bg;

      &::before {
        background-image: url('@/assets/svg/login-bg-dark.svg');
      }

      .ant-input,
      .ant-input-password,
      .ant-input-affix-wrapper,
      .ant-checkbox-inner {
        background-color: #232a3b;
      }

      .ant-btn:not(.ant-btn-link, .ant-btn-primary) {
        border: 1px solid #4a5569;
      }

      &-form {
        background: transparent !important;
      }

      .app-iconify {
        color: #fff;
      }

      input.fix-auto-fill,
      .fix-auto-fill input {
        // -webkit-text-fill-color: #c9d1d9 !important;
        box-shadow: inherit !important;
      }

      .ant-divider-inner-text {
        color: @text-color-secondary;
        font-size: 12px;
      }
    }
  }

  .@{prefix-cls} {
    min-height: 100%;
    overflow: hidden;

    /* stylelint-disable-next-line media-query-no-invalid */
    @media (max-width: @screen-xl) {
      background-color: #293146;

      .@{prefix-cls}-form {
        background-color: #fff;
      }
    }

    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      margin-left: -48%;
      background-image: url('@/assets/svg/login-bg.svg');
      background-repeat: no-repeat;
      background-position: 100%;
      background-size: auto 100%;
      /* stylelint-disable-next-line media-query-no-invalid */
      @media (max-width: @screen-xl) {
        display: none;
      }
    }

    .@{logo-prefix-cls} {
      position: absolute;
      top: 12px;
      height: 30px;

      &__title {
        color: #fff;
        font-size: 16px;
      }

      img {
        width: 32px;
      }
    }

    .container {
      .@{logo-prefix-cls} {
        display: flex;
        width: 60%;
        height: 80px;

        &__title {
          color: #fff;
          font-size: 24px;
        }

        img {
          width: 48px;
        }
      }
    }

    &-sign-in-way {
      .anticon {
        color: #888;
        font-size: 22px;
        cursor: pointer;

        &:hover {
          color: @primary-color;
        }
      }
    }

    input:not([type='checkbox']) {
      min-width: 360px;
      /* stylelint-disable-next-line media-query-no-invalid */
      @media (max-width: @screen-xl) {
        min-width: 320px;
      }
      /* stylelint-disable-next-line media-query-no-invalid */
      @media (max-width: @screen-lg) {
        min-width: 260px;
      }
      /* stylelint-disable-next-line media-query-no-invalid */
      @media (max-width: @screen-md) {
        min-width: 240px;
      }
      /* stylelint-disable-next-line media-query-no-invalid */
      @media (max-width: @screen-sm) {
        min-width: 160px;
      }
    }

    .@{countdown-prefix-cls} input {
      min-width: unset;
    }
  }
</style>
